var util = require("../util"), checkInterval = 500;

module.exports = function(e, n, r) {
    function t(e, n, r) {
        var i = 0, u = e.tagName;
        if ("SCRIPT" !== u && "STYLE" !== u && "META" !== u && "HEAD" !== u) {
            var c = e.children ? e.children.length : 0;
            if (c > 0) for (var l = e.children, a = c - 1; a >= 0; a--) i += t(l[a], n + 1, i > 0);
            if (i <= 0 && !r) {
                if (!(e.getBoundingClientRect && e.getBoundingClientRect().top < o)) return 0;
            }
            i += 1 + .5 * n;
        }
        return i;
    }
    function i(e) {
        for (var n = 1; n < e.length; n++) if (e[n].score < e[n - 1].score) return e.splice(n, 1), 
        i(e);
        return e;
    }
    var o = n.innerHeight || 0, u = [], c = null, l = 0;
    util.ext(e.prototype, {
        initFmpObserver: function(e) {
            var i = this;
            if (!i._conf || !i._conf.useFmp) return null;
            if (!n.MutationObserver) return util.warn("[retcode] first meaningful paint can not be retrieved"), 
            i.sendPerformance(), null;
            util.on(n, "beforeunload", function() {
                i.endObserving(0, !0);
            });
            var o = n.MutationObserver;
            return (c = new o(function() {
                !function(e) {
                    var n = Date.now() - e, i = r.querySelector("body");
                    if (i) {
                        var o = 0;
                        o += t(i, 1, !1), u.push({
                            score: o,
                            t: n
                        });
                    } else u.push({
                        score: 0,
                        t: n
                    });
                }(i._startTime);
            })).observe(document, {
                childList: !0,
                subtree: !0
            }), l = 1, i.onReady(function() {
                i.endObserving(e);
            }), c;
        },
        endObserving: function(e, n) {
            var r = this;
            if (c && l) if (r.fmpTimmer && (clearTimeout(r.fmpTimmer), r.fmpTimmer = null), 
            n || !function(e, n) {
                var r = Date.now() - e;
                return !(r > n || r - (u && u.length && u[u.length - 1].t || 0) > 2 * checkInterval);
            }(r._startTime, e)) {
                c.disconnect(), l = 0, u = i(u);
                for (var t = null, o = 1; o < u.length; o++) if (u[o].t >= u[o - 1].t) {
                    var a = u[o].score - u[o - 1].score;
                    (!t || t.rate <= a) && (t = {
                        t: u[o].t,
                        rate: a
                    });
                }
                t && t.t > 0 && t.t < 36e5 ? r.sendPerformance({
                    fmp: t.t
                }) : r.sendPerformance();
            } else r.fmpTimmer = util.delay(function() {
                r.endObserving(e);
            }, checkInterval);
        }
    });
};